﻿/*
-----------------------------------------------------------------------------
This source file is part of Cell Cloud.

Copyright (c) 2009-2012 Cell Cloud Team - cellcloudproject@gmail.com

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/

#ifndef CellString_h
#define CellString_h

#include "CellPrerequisites.h"

// 如果使用 GCC 3.1 C++ STD lib
#if CELL_COMPILER == CELL_COMPILER_GNUC && CELL_COMP_VER >= 310 && !defined(STLPORT)

// For gcc 4.3 see http://gcc.gnu.org/gcc-4.3/changes.html
#   if CELL_COMP_VER >= 430
#       include <tr1/unordered_map> 
#   else
#       include <ext/hash_map>
namespace __gnu_cxx
{
    template <> struct hash< cell::_StringBase >
    {
        size_t operator()( const cell::_StringBase _stringBase ) const
        {
            /* This is the PRO-STL way, but it seems to cause problems with VC7.1
               and in some other cases (although I can't recreate it)
            hash<const char*> H;
            return H(_stringBase.c_str());
            */
            /** This is our custom way */
            register size_t ret = 0;
            for( cell::_StringBase::const_iterator it = _stringBase.begin(); it != _stringBase.end(); ++it )
                ret = 5 * ret + *it;

            return ret;
        }
    };
}
#   endif

#endif

namespace cell
{
/** \addtogroup Core
 *  @{
 */
/** \addtogroup General
 *  @{
 */

/** 字符串操作实用类。 */
class _CellExport StringUtil
{
public:
	typedef StringStream StrStreamType;

	/** 删除字符串两端的空白字符。
	@remarks
		空格和制表符都是空白字符。
	*/
	static void trim( String& str, bool left = true, bool right = true );

	/** 返回根据指定子串进行分割后的字符串数组。
	@param str 待分割的字符串。
	@param delims 指定分割定界符。
	@param maxSplits 指定最大拆分数量。
	*/
	static vector< String >::type split( const String& str, const String& delims = "\t\n ", unsigned int maxSplits = 0);

	/**
	*/
	static vector< String >::type tokenise( const String& str, const String& delims = "\t\n ", const String& doubleDelims = "\"", unsigned int maxSplits = 0);

	/** 将字符串内的字符全部转为小写。
	*/
	static void toLowerCase(String& str);

	/** 将字符串内的字符全部转为大写。
	*/
	static void toUpperCase(String& str);

	/** 判断字符串起始字符与指定字符串是否相同。
	*/
	static bool startsWith(const String& str, const String& pattern, bool lowerCase = false);

	/** 判断字符串结束字符与指定字符串是否相同。
	*/
	static bool endsWith(const String& str, const String& pattern, bool lowerCase = false);

	/** 标准化路径。
	*/
	static String standardisePath(const String &init);

	/** 将制定的全路径拆分出文件名和路径。
	*/
	static void splitFilename(const String& qualifiedName,
		String& outBasename, String& outPath);

	/** 将制定的全路径拆分出文件名、扩展名和路径。
	*/
	static void splitFullFilename(const cell::String& qualifiedName, 
		cell::String& outBasename, cell::String& outExtention, 
		cell::String& outPath);

	/** 将制定的全路径拆分出文件名和扩展名。
	*/
	static void splitBaseFilename(const cell::String& fullName, 
		cell::String& outBasename, cell::String& outExtention);


	/** 进行简单的字符串模板匹配。
	*/
	static bool match(const String& str, const String& pattern, bool caseSensitive = true);

	/** 替换字符窜内与指定字符匹配的所有字符。
	*/
	static const String replaceAll(const String& source, const String& replaceWhat, const String& replaceWithWhat);

	/// 空字符串常量，即长度为 0 的字符串。
	static const String BLANK;
};


#if CELL_COMPILER == CELL_COMPILER_GNUC && CELL_COMP_VER >= 310 && !defined(STLPORT)
#   if CELL_COMP_VER < 430
	typedef ::__gnu_cxx::hash< _StringBase > _StringHash;
#   else
	typedef ::std::tr1::hash< _StringBase > _StringHash;
#   endif
#elif CELL_COMPILER == CELL_COMPILER_MSVC && CELL_COMP_VER >= 1600 && !defined(STLPORT) // VC++ 10.0
	typedef ::std::tr1::hash< _StringBase > _StringHash;
#elif !defined( _STLP_HASH_FUN_H )
	typedef stdext::hash_compare< _StringBase, std::less< _StringBase > > _StringHash;
#else
	typedef std::hash< _StringBase > _StringHash;
#endif

// Convert wstring to string
std::string wstr_to_str(const std::wstring& arg);

// Convert string to wstring
std::wstring str_to_wstr(const std::string& arg);

/** @} */
/** @} */
} // end namespace cell

#endif // CellString_h
